/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: qian
 * Date: 2022-06-29
 * Time: 16:38
 */
//无头双链表
public class MyLinkedList {
    static class ListNode{
        public int val;
        public ListNode prev;//前一个节点
        public  ListNode next;//下一个节点
        public ListNode(int val){
            this.val=val;
        }
    }
    public ListNode head;
    public ListNode last;

    //头插法
    public void addFirst(int data){
        ListNode listNode=new ListNode(data);
        if(this.head==null){
            this.head=listNode;
            this.last=listNode;
        }else {
            listNode.next=this.head;
            this.head.prev=listNode;
            this.head=listNode;
        }
    }
    //尾插法
    public void addLast(int data){
        ListNode listNode=new ListNode(data);
        if(this.head==null){
            this.head=listNode;
            this.last=listNode;
        }else {
            this.last.next=listNode;
            listNode.prev= this.last;
            this.last=listNode;
        }
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data) throws MyLinkedListIndexOutofException {
        if(index<0 || index>size()){
            throw new MyLinkedListIndexOutofException("下标位置不合法");
        }
        if(index==0){
            addFirst(data);
            return;
        }
        if(index==size()){
            addLast(data);
            return;
        }
        ListNode listNode=new ListNode(data);
        ListNode cur=findIndex(index);
        listNode.next=cur.next;
        cur.next.prev=listNode;
        cur.next=listNode;
        listNode.prev=cur;
    }
    private ListNode findIndex(int index){
        ListNode cur=this.head;
        while((index-1)!=0){
            cur=cur.next;
            index--;
        }
        return cur;
    }
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur=this.head;
        while(cur!=null){
            if(cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }
    //删除第一次出现关键字为key的节点
    public void remove(int key){
        ListNode cur=this.head;
        while (cur!=null){
            if(key==cur.val){
                if(this.head==this.last){
                    this.head=null;
                    this.last=null;
                }else if(cur==this.head){
                    this.head=this.head.next;
                    this.head.prev=null;
                    cur.next=null;
                }else if(cur==this.last){
                    this.last=this.last.prev;
                    this.last.next=null;
                    cur.prev=null;
                }else{
                    cur.prev.next=cur.next;
                    cur.next.prev=cur.prev;
                }
                break;
            }else{
                cur=cur.next;
            }
        }
    }
    //删除所有值为key的节点
    public void removeAllKey(int key){
        ListNode cur=this.head;
        while (cur!=null){
            if(key==cur.val){
                if(this.head==this.last){
                    this.head=null;
                    this.last=null;
                }else if(cur==this.head){
                    this.head=this.head.next;
                    this.head.prev=null;
                }else if(cur==this.last){
                    this.last=this.last.prev;
                    this.last.next=null;
                }else{
                    cur.prev.next=cur.next;
                    cur.next.prev=cur.prev;
                }

            }
            cur=cur.next;
        }
    }
    //得到单链表的长度
    public int size(){
        int count=0;
        ListNode cur=this.head;
        while(cur!=null){
            count++;
            cur=cur.next;
        }
        return count;
    }
    public void display(){
        ListNode cur=this.head;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }
    public void clear(){
        ListNode cur=this.head;
        while(cur!=null){
            ListNode curNext=cur.next;
            cur.next=null;
            cur.prev=null;
            cur=curNext;
        }
        this.head=null;
        this.last=null;
    }

}
